package com.btpn.custody.web.m001.action;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.validation.SkipValidation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;

import com.btpn.custody.dao.IArea;
import com.btpn.custody.dao.IBranch;
import com.btpn.custody.entity.Area;
import com.btpn.custody.entity.Branch;
import com.btpn.custody.service.IGlobalService;
import com.btpn.custody.web.m001.model.BranchModel;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.validator.annotations.EmailValidator;
import com.opensymphony.xwork2.validator.annotations.ExpressionValidator;
import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
import com.opensymphony.xwork2.validator.annotations.Validations;
import com.opensymphony.xwork2.validator.annotations.ValidatorType;

@ParentPackage(value="custody")
@Results({
	@Result(name="input", location="t_branch")
})
@Validations(
	requiredStrings = {
			@RequiredStringValidator(type = ValidatorType.SIMPLE, fieldName = "branchCode", message = "Branch Code must be filled"),
			@RequiredStringValidator(type = ValidatorType.SIMPLE, fieldName = "branchName", message = "Branch Name must be filled")
	},
	emails = {
			@EmailValidator(type = ValidatorType.SIMPLE, fieldName = "branchEmail", message = "Email must valid")
	},
	expressions = {
            @ExpressionValidator(expression = "areaId != -1", message = "Area must be choose")
	}
)
public class BranchAction extends ActionSupport implements ServletRequestAware, Preparable {
	
	private static final long serialVersionUID = -7374071805269399351L;
	
	@Autowired
	private IArea areaDaoHibernate;
	
	@Autowired
	private IBranch branchDaoHibernate;

	@Autowired
	private IGlobalService globalService;
	
	private HttpServletRequest request;
	
	private Long branchId;
	private String branchCode;
	private String branchName;
	private String branchEmail;
	private Long areaId;
	
	private Long _chk[];
	private List<Area> areas;
	private List<BranchModel> branchModels;
	
	@SkipValidation
	@Action(value = "/listBranch", results = { @Result(name="success", location="t_branch") })
	public String execute() throws Exception {
		
		setBranchId(0L);
		setBranchCode("");
		setBranchName("");
		setBranchEmail("");
		setAreaId(0L);
		
		return SUCCESS;
	}
	
	@SkipValidation
	@Action(value = "/editBranch", results = { 
			@Result(name="success", location="t_branch"),
			@Result(name="error", type="redirectAction", params = {"actionName", "listBranch"})
	})
	public String editBranch() throws Exception {
		
		String id = getRequest().getParameter("id");
		if (id != null) {
			Branch editedBranch = branchDaoHibernate.get(Long.parseLong(id));
			setBranchId(editedBranch.getId());
			setBranchCode(editedBranch.getCode());
			setBranchName(editedBranch.getName());
			setBranchEmail(editedBranch.getEmail());
			setAreaId(editedBranch.getArea().getId());
			
			return SUCCESS;
		} else {
			return ERROR;
		}
	}
	
	@Action(value = "/addOrUpdateBranch", results = { 
			@Result(name="success", type="redirectAction", params = {"actionName", "listBranch"} )
	})
	public String addOrUpdateBranch() throws Exception {
		
		if (branchId == 0L) {			// create : with validation		
			// validate branch code
			Branch theBranch = branchDaoHibernate.getByCode(branchCode);
			if (theBranch != null) {
				addFieldError("branchCode", "Branch Code must be unique");				
				return INPUT;
			}
			
			// validate branch name
			theBranch = branchDaoHibernate.getByName(branchName);
			if (theBranch != null) {
				addFieldError("branchName", "Branch Name have been exist");				
				return INPUT;
			}
		}
		
		globalService.createOrUpdateBranch(branchId, branchCode, branchName, branchEmail, areaId, SecurityContextHolder.getContext().getAuthentication().getName());
		
		return SUCCESS;
	}	
	
	@SkipValidation
	@Action(value = "/removeBranchs", results = { 
			@Result(name="success", type="redirectAction", params = {"actionName", "listBranch"} )
	})
	public String removeBranchs() throws Exception {
		
		globalService.deleteBranchs(_chk, SecurityContextHolder.getContext().getAuthentication().getName());
			
		return SUCCESS;
	}
	
	@Override
	public void prepare() throws Exception {
		areas = areaDaoHibernate.findAll();
		
		branchModels = globalService.findAllBranchModel();
	}

	public String getBranchCode() {
		return branchCode;
	}

	public void setBranchCode(String branchCode) {
		this.branchCode = branchCode;
	}

	public String getBranchEmail() {
		return branchEmail;
	}

	public void setBranchEmail(String branchEmail) {
		this.branchEmail = branchEmail;
	}
	
	public String getBranchName() {
		return branchName;
	}

	public void setBranchName(String branchName) {
		this.branchName = branchName;
	}

	public Long getAreaId() {
		return areaId;
	}

	public void setAreaId(Long areaId) {
		this.areaId = areaId;
	}

	public List<Area> getAreas() {
		return areas;
	}

	public void setAreas(List<Area> areas) {
		this.areas = areas;
	}

	public List<BranchModel> getBranchModels() {
		return branchModels;
	}

	public void setBranchModels(List<BranchModel> branchModels) {
		this.branchModels = branchModels;
	}

	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

	public HttpServletRequest getRequest() {
		return request;
	}

	public Long getBranchId() {
		return branchId;
	}

	public void setBranchId(Long branchId) {
		this.branchId = branchId;
	}

	public Long[] get_chk() {
		return _chk;
	}

	public void set_chk(Long[] _chk) {
		this._chk = _chk;
	}
}
